<template>
  <view class="snowy-form">
    <uni-forms ref="formRef"
               :model="formData"
               label-position="top"
               :rules="rules"
               validate-trigger="blur"
               labelWidth="auto">
      <uni-forms-item label="预约日期"
                      name="reservationDate"
                      :required="true"
                      :rules="[{ required: true, errorMessage: '请选择预约日期' }]">
        <uni-datetime-picker
            type="date"
            v-model="formData.reservationDate"
            :start="startDate"
            :end="endDate"
            :disableBefore="startDate"
            @change="handleDateChange"
            :clear-icon="false"
            :border="true"
            placeholder="请选择预约日期"
        />
      </uni-forms-item>
      <uni-forms-item label="预约时间段"
                      name="timeSlot"
                      :required="true"
                      :rules="[{ required: true, errorMessage: '请输入预约时间段' }]">
        <snowy-sel-picker :map="{key: 'value', label: 'text'}"
                          v-model="formData.timeSlot"
                          @getOptData="getTimeSlotOptions"
                          @change="handleTimeSlotChange"
                          placeholder="请选择预约时间段"
                          :disabled="!formData.reservationDate"></snowy-sel-picker>
      </uni-forms-item>
      <uni-forms-item label="设备类型"
                      name="type"
                      :required="true"
                      :rules="[{ required: true, errorMessage: '请输入设备类型' }]">
        <snowy-sel-picker :map="{key: 'value', label: 'text'}"
                          v-model="formData.type"
                          @getOptData="getTypeOptions"
                          placeholder="请选择设备类型"></snowy-sel-picker>
      </uni-forms-item>
      <uni-forms-item label="设备名称"
                      name="deviceName"
                      :required="true"
                      :rules="[{ required: true, errorMessage: '请选择您要预约的设备' }]">
        <uni-data-select
            v-model="formData.deviceName"
            :localdata="deviceNameOptions"
            :clear="false"
            :disabled="!formData.type || !formData.timeSlot"
            @change="handleDeviceChange"
            placeholder="请选择您要预约的设备"
        ></uni-data-select>
      </uni-forms-item>
      <uni-forms-item label="预约用户名称"
                      name="userName"
                      :required="true"
                      :rules="[{ required: true, errorMessage: '请输入预约用户名称' }]">
        <uni-easyinput v-model="formData.userName"
                       placeholder="请输入预约用户名称"></uni-easyinput>
      </uni-forms-item>
      <uni-forms-item label="使用目的"
                      name="purpose"
                      :required="false"
                      :rules="[{ required: false, errorMessage: '请输入使用目的' }]">
        <uni-easyinput v-model="formData.purpose"
                       placeholder="请输入使用目的"></uni-easyinput>
      </uni-forms-item>
      <uni-forms-item label="备注"
                      name="remark"
                      :required="false"
                      :rules="[{ required: false, errorMessage: '请输入备注' }]">
        <uni-easyinput v-model="formData.remark"
                       placeholder="请输入备注"></uni-easyinput>
      </uni-forms-item>
    </uni-forms>
    <tui-button margin="50rpx 0"
                :preventClick="true"
                :shadow="true"
                @click="submit">提交</tui-button>
  </view>
</template>

<script setup name="deviceReservationForm">
import storage from "@/utils/storage";
import { onLoad } from "@dcloudio/uni-app"
import deviceReservationApi from '@/api/biz/device-reservation-api'
import deviceInfoApi from "@/api/biz/device-info-api";
import bizDictApi from "@/api/biz/biz-dict-api";
import { reactive, ref, getCurrentInstance, watch, computed  } from "vue"
import CallbackState from "@/enum/callback-state"
import dayjs from "dayjs"
// 引入 isSameOrBefore 插件
import isSameOrBefore from 'dayjs/plugin/isSameOrBefore'
// 使用插件
dayjs.extend(isSameOrBefore)
import UniForms from "../../../uni_modules/uni-forms/components/uni-forms/uni-forms.vue";
import UniFormsItem from "../../../uni_modules/uni-forms/components/uni-forms-item/uni-forms-item.vue";

const { proxy } = getCurrentInstance()
const formRef = ref()
const formData = ref({})
// 常用正则规则大全：https://any86.github.io/any-rule/
// 去pages/biz/user/form.vue中寻找示例
const rules = reactive({})

const getTypeOptions = (param, callback) => callback({ state: CallbackState.SUCCESS, data: uni.$snowy.tool.dictList('DEVICE_TYPE') })
const getTimeSlotOptions = (param, callback) => callback({ state: CallbackState.SUCCESS, data: timeSlotOptions.value })
const deviceNameOptions = ref([]) // 设备名称选项
const timeSlotOptions = ref([]) // 将用于显示给用户的、可能被过滤的时间段
const allTimeSlots = ref([]) // 用于存储从API获取的全部时间段

watch(() => formData.value.type, (newType, oldType) => {
  if (newType !== oldType) {
    handleTypeChange(newType);
  }
});

// 日期禁用相关
const startDate = ref(dayjs().format('YYYY-MM-DD')) // 今天
const endDate = ref(dayjs().add(6, 'day').format('YYYY-MM-DD')) // 今天后的第6天

// 处理日期变化
const handleDateChange = (newDate) => {
  if (newDate) { // 这个b组件不支持禁用其中某些日期，只能通过提示框提示了
    const selectedDay = dayjs(newDate).day()
    if (selectedDay === 0 || selectedDay === 6) {
      uni.showToast({ title: '周末暂时不可预约，请重新选择', icon: 'none' })
      setTimeout(() => {
        formData.value.reservationDate = ''
      }, 100)
      return
    }

    updateDisplayedTimeSlots()
    if (formData.value.type && formData.value.timeSlot) {
      updateDeviceOptions()
    } else {
      deviceNameOptions.value = []
      formData.value.deviceName = undefined
    }
  }
}

const handleTimeSlotChange = () => {
  // 清空设备名称，强制用户重新选择
  formData.value.deviceName = undefined

  if (formData.value.type && formData.value.reservationDate && formData.value.timeSlot) {
    updateDeviceOptions()
  } else {
    deviceNameOptions.value = []
  }
}

const handleTypeChange = (value) => {
  formData.value.deviceName = undefined
  if (value) {
    if (formData.value.reservationDate && formData.value.timeSlot) {
      updateDeviceOptions()
    } else {
      getDevicesByType(value)
    }
  } else {
    deviceNameOptions.value = []
  }
}

// 根据设备类型获取设备列表
const getDevicesByType = (type) => {
  deviceInfoApi
      .deviceInfoListByType({ type: type })
      .then((res) => {
        if (res) {
          deviceNameOptions.value = res.map((item) => {
            return {
              text: item.name,
              value: item.name,
              deviceId: item.id,
              disable: false
            }
          })
        } else {
          deviceNameOptions.value = []
        }
      })
      .catch(() => {
        deviceNameOptions.value = []
      })
}

// 更新设备选项，标记已预约的设备
const updateDeviceOptions = () => {
  if (!formData.value.type || !formData.value.reservationDate || !formData.value.timeSlot) {
    return
  }

  // 添加加载提示
  uni.showLoading({
    title: '加载设备中...'
  })

  const params = {
    type: formData.value.type,
    reservationDate: formData.value.reservationDate,
    timeSlot: formData.value.timeSlot,
    id: formData.value.id || ''
  }

  // 先获取该类型的所有设备
  deviceInfoApi
      .deviceInfoListByType({ type: formData.value.type })
      .then((allDevices) => {
        if (allDevices && allDevices.length > 0) {
          deviceReservationApi
              .getReservedDevices(params)
              .then((reservedDevices) => {
                if (reservedDevices && reservedDevices.length > 0) {
                  deviceNameOptions.value = allDevices.map((device) => {
                    const isReserved = reservedDevices.includes(device.name)
                    return {
                      text: device.name + (isReserved ? ' (已预约)' : ''),
                      value: device.name,
                      deviceId: device.id,
                      disable: isReserved
                    }
                  })

                  if (!formData.value.id && formData.value.deviceName && reservedDevices.includes(formData.value.deviceName)) {
                    formData.value.deviceName = undefined
                    uni.showToast({ title: '该设备在所选时间段已被预约，请重新选择', icon: 'none' });
                  }
                } else {
                  deviceNameOptions.value = allDevices.map((device) => {
                    return {
                      text: device.name,
                      value: device.name,
                      deviceId: device.id,
                      disable: false
                    }
                  })
                }
              })
              .catch(() => {
                deviceNameOptions.value = allDevices.map((device) => {
                  return {
                    text: device.name,
                    value: device.name,
                    deviceId: device.id,
                    disable: false
                  }
                })
              })
        } else {
          deviceNameOptions.value = []
          uni.hideLoading()
        }
      })
      .catch(() => {
        deviceNameOptions.value = []
        uni.hideLoading()
      })
}

// 更新并过滤显示的时间段选项
const updateDisplayedTimeSlots = () => {
  if (!allTimeSlots.value.length) {
    timeSlotOptions.value = []
    return
  }
  if (!formData.value.reservationDate) {
    // 如果没有选择日期，显示所有原始时间段（或根据业务逻辑清空）
    timeSlotOptions.value = [...allTimeSlots.value]
    return
  }

  const selectedDate = dayjs(formData.value.reservationDate).startOf('day')
  const today = dayjs().startOf('day')

  if (selectedDate.isSame(today, 'day')) {
    // 如果选择的是今天
    const now = dayjs() // 获取当前精确时间
    timeSlotOptions.value = allTimeSlots.value.filter((slot) => {
      const startTimeStr = slot.value.split('-')[0]
      const [hour, minute] = startTimeStr.split(':').map(Number)
      // 构建该时间段在今天的开始时间点
      const slotStartDateTime = dayjs().hour(hour).minute(minute).second(0).millisecond(0)
      return now.isBefore(slotStartDateTime)
    })

    // 检查当前已选的时间段是否仍然有效
    if (formData.value.timeSlot) {
      const isCurrentSlotStillAvailable = timeSlotOptions.value.some(
          (option) => option.value === formData.value.timeSlot
      )
      if (!isCurrentSlotStillAvailable) {
        formData.value.timeSlot = undefined
        uni.showToast({ title: '原选择的时间段已过或不可用，请重新选择', icon: 'none' }) // 修改为uni.showToast，message.warning不存在
        deviceNameOptions.value = []
        formData.value.deviceName = undefined
      }
    }
  } else {
    timeSlotOptions.value = [...allTimeSlots.value]
  }
}

// 处理设备选择变化
const handleDeviceChange = (value) => {
  if (value) {
    const selectedDevice = deviceNameOptions.value.find(device => device.value === value)
    if (selectedDevice && selectedDevice.disable) {
      uni.showToast({ title: '该设备已被预约，请选择其他设备', icon: 'none' })
      setTimeout(() => {
        formData.value.deviceName = undefined
      }, 100)
    }
  }
}

onLoad((option) => {
  // 新增模式
  if(!option.id){
    // 异步获取所有时间段
    bizDictApi.treeByDict({ dictName: 'TIME_SLOT' }).then((res) => {
      allTimeSlots.value = res.map((item) => {
        return {
          text: item.dictLabel,
          value: item.dictValue
        }
      })
      // 初始化时间段选项
      updateDisplayedTimeSlots()
    }).catch(error => {
      console.error('获取时间段失败:', error)
      uni.showToast({ title: '获取时间段失败', icon: 'none' })
    })

    // 自动填入当前用户名
    const userInfo = storage.get('userInfo')
    if (userInfo && userInfo.name) {
      formData.value.userName = userInfo.name
    }

    return
  }
  // 编辑模式
  deviceReservationApi.deviceReservationDetail({
    id: option.id
  }).then(data => {
    formData.value = data
  })
})

// 监听时间段变化
watch(() => formData.value.timeSlot, (newTimeSlot, oldTimeSlot) => {
  if (newTimeSlot !== oldTimeSlot) {
    handleTimeSlotChange();
  }
});

const submit = () => {
  formRef.value.validate().then(res => {
    // 显示预约中状态
    uni.showLoading({
      title: '预约中...',
      mask: true // 添加遮罩防止用户重复点击
    })

    deviceReservationApi
        .deviceReservationSubmitForm(formData.value, !formData.value.id)
        .then(data => {
          // 隐藏加载提示
          uni.hideLoading()

          // 显示预约成功提示
          uni.showToast({
            title: '预约成功',
            icon: 'success',
            duration: 2000
          })

          // 延迟返回，让用户看到成功提示
          setTimeout(() => {
            uni.$emit('formBack', {
              data: data
            })
            uni.navigateBack({
              delta: 1
            })
          }, 1500)
        })
        .catch(error => {
          // 隐藏加载提示
          uni.hideLoading()

          // 显示错误提示
          uni.showToast({
            title: '预约失败，请重试',
            icon: 'none',
            duration: 2000
          })

          console.error('预约失败:', error)
        })
  }).catch(errors => {
    // 表单验证失败
    uni.showToast({
      title: '请完善表单信息',
      icon: 'none'
    })
  })
}
</script>
<style lang="scss" scoped>
</style>
